package com.djx.locks;


import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;

import java.util.Collections;
import java.util.List;

public class MyLock {

    private final String myIP = "192.168.15.132:2181";

    ZooKeeper zooKeeper;
    private static final String LOCK_ROOT_PATH = "/locks";
    private static final String LOCK_NODE_NAME = "/lock_";
    private String lockPath;

    public MyLock() {
        try {
            zooKeeper = new ZooKeeper(myIP, 10000, new Watcher() {
                public void process(WatchedEvent watchedEvent) {
                    if (watchedEvent.getType() == Event.EventType.None) {

                        if (Event.KeeperState.SyncConnected == watchedEvent.getState()) {
                            System.out.println("连接成功!!!!!!!!!");
                        }
                    }
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void acquireLock() throws Exception {
        //创建锁节点
        createLock();
        //尝试获取锁
        attempLock();
    }

    //创建锁节点
    private void attempLock() throws Exception {
        List<String> list = zooKeeper.getChildren(LOCK_ROOT_PATH, false);

        Collections.sort(list);

        int index = list.indexOf(lockPath.substring(LOCK_ROOT_PATH.length()+1));

        if (index == 0) {
            System.out.println("获取到锁成功!");
            return;
        } else {
            //获取上一个节点的路径
            String path = list.get(index - 1);
            Stat stat = zooKeeper.exists(LOCK_ROOT_PATH + path, watcher);
            if (stat == null) {
                attempLock();
            } else {
                synchronized (watcher) {
                    watcher.wait();
                }
                attempLock();
            }
        }
    }

    //尝试获取锁
    private void createLock() throws Exception {
        //判断locks节点是否存在 ,不存在创建
        Stat stat = zooKeeper.exists(LOCK_ROOT_PATH, false);
        if (stat == null) {
            //创建持久化节点
            zooKeeper.create(LOCK_ROOT_PATH, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
        //创建临时有序节点
        lockPath = zooKeeper.create(LOCK_ROOT_PATH + LOCK_NODE_NAME, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);


    }

    Watcher watcher = new Watcher() {
        public void process(WatchedEvent event) {
            if (event.getType() == Event.EventType.NodeDeleted) {
                synchronized (this) {
                    notifyAll();
                }
            }
        }
    };

    //释放锁
    public void releaseLock() throws Exception {
//        System.out.println("释放锁 ::: " + lockPath);
        zooKeeper.delete(this.lockPath, -1);
//        System.out.println("删除临时有序节点成功");
        zooKeeper.close();
        System.out.println("锁释放::: " + this.lockPath);
        System.out.println("zookepper连接关闭!");
    }

}
